home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
scope
/
151-175
/
scopedisk168
/
tinytools
/
tee
/
tee.asm
< prev
next >
Wrap
Assembly Source File
|
1995-03-19
|
5KB
|
198 lines
; Tee, split stdinput to stdoutput and multiple file streams.
INCLUDE "/include/init.i"
; Local Equs
BufSize EQU 512
Handles EQU BufSize
; Variable storage
STRUCT ArgArray,(2+1)*4 ; +1 'cause I'm parnoid
SIZE
; Regs
AppendBool EQUR D4
StdInput EQUR D5
AllocStruct EQUR D6
ActualLength EQUR D7
FileNamePtrPtr EQUR A2
HandlePtr EQUR A3
ErrorStrPtr EQUR A4
; Start
STACK 4000
INIT
; Let ARP interpret the commandline
MOVE.L ComLineBase(GP),A0
MOVE.L ComLineSize(GP),D0
LEA HelpMsg(PC),A1
LEA ArgArray(GP),A2
LEA Template(PC),A3
MOVE.L A1,(A2)
CALL GADS
TST.L D0
BEQ.S UnusableArgs
BPL.S ArgsMightBeOK
UnusableArgs:
MOVE.L (A2),ErrorStrPtr
BRA ErrorExit
ArgsMightBeOK:
; Fetch the -a switch and check if at least one file present.
MOVE.L 4(A2),AppendBool
BEQ.S ArgsOK
LEA HelpMsg(PC),ErrorStrPtr
MOVEQ #1,D1
CMP.L D0,D1
BEQ ErrorExit
ArgsOK:
; Alloc tracked mem for the read write buf and the handles.
LEA OutOfMem(PC),ErrorStrPtr
ADDQ.L #1+1,D0 ; Make space for StdOut + null termination
LSL.L #2,D0 ; in the file handles longword array.
ADD.L #BufSize,D0 ; Buffer and Handles use same mem allocation
MOVEQ #0,D1
CALL ArpAllocMem
MOVE.L D0,AllocStruct ; Data reg, so Z gets set
BEQ ErrorExit
; Initialize the handle and filename longword array pointers
MOVE.L ArgArray(GP),FileNamePtrPtr
MOVE.L AllocStruct,A0
LEA Handles(A0),HandlePtr
; Open the standard input and output
CALL Input
MOVE.L D0,StdInput
CALL Output
MOVE.L D0,(HandlePtr)+
;----- The open the files, and seek to end loop
LEA OpenError(PC),ErrorStrPtr
OpenNextFile:
TST.L (FileNamePtrPtr)
BEQ.S AllFilesOpened
; If Appending, try to open (tracked) the file as an old file
TST.L AppendBool
BEQ.S NoAppendingRequested
MOVE.L (FileNamePtrPtr),D1
MOVE.L #MODE_OLDFILE,D2
CALL ArpOpen
MOVE.L D0,(HandlePtr)
BEQ.S TryToOpenNewFile
; Seek to the end
MOVE.L D0,D1
MOVEQ #0,D2
MOVE.L #OFFSET_END,D3
CALL Seek
ADDQ.L #1,D0
BEQ ErrorExit
BRA.S IncrementAndLoop
NoAppendingRequested:
; Open files (tracked) as new
TryToOpenNewFile:
MOVE.L (FileNamePtrPtr),D1
MOVE.L #MODE_NEWFILE,D2
CALL ArpOpen
MOVE.L D0,(HandlePtr)
BEQ ErrorExit
; Update pointers and loop back
IncrementAndLoop:
ADDQ.L #4,FileNamePtrPtr
ADDQ.L #4,HandlePtr
BRA OpenNextFile
AllFilesOpened:
CLR.L (HandlePtr) ; Null termination
;----- The single input multi output copy loop, check for ^C & initize
DoNextRdWrChunk:
SUB.L A1,A1
CALL CheckAbort
MOVE.L A1,ErrorStrPtr
TST.L D0
BNE.S ErrorExit
LEA WriteError(PC),ErrorStrPtr
MOVE.L AllocStruct,A0
LEA Handles(A0),HandlePtr ; Reset to start of array
; Read from the standard input until EOF or error
MOVE.L StdInput,D1
MOVE.L AllocStruct,D2
MOVE.L #BufSize,D3
CALL Read
MOVE.L D0,ActualLength
BEQ.S Exit
BMI.S ErrorExit
; Do the multiwrite, and loop back
DoNextWrite:
MOVE.L (HandlePtr)+,D1
BEQ DoNextRdWrChunk
MOVE.L AllocStruct,D2
MOVE.L ActualLength,D3
CALL Write
CMP.L D0,D3
BNE.S ErrorExit
BRA DoNextWrite
; Done, cleanup
Exit:
CLR.W ReturnCode(GP)
SUB.L ErrorStrPtr,ErrorStrPtr
ErrorExit:
; Display error string, if any, and exit
MOVE.L ErrorStrPtr,D0
BEQ.S NoErrorMsg
MOVE.L D0,A1
CALL Puts
NoErrorMsg:
RTS
; The string section
Template:
DC.B 'Files/...,-a=APPEND/s',0
HelpMsg:
DC.B 'Tee - pipe fitting.',10
DC.B 'Usage: Tee [-a] <File> [...]',0
OutOfMem:
DC.B 'Out of memory!',0
OpenError:
DC.B 'Tee-file could not be opened',10
WriteError:
DC.B 'Error while writing to tee-file',0
CNOP 0,2
END